package com.fz.us.oa.web.shiro.credentials;

import com.fz.us.admin.base.cache.CacheConstants;
import com.fz.us.admin.base.service.redis.ShardedRedisService;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 登录的用户名匹配的校验在此处进行
 * 限定用户输入密码错误次数
 */
public class LoginHashedCredentialsMatcher extends HashedCredentialsMatcher {

    private static final int MAX_RETRY_SECOND = 10*60;// 10分钟
    private static final int MAX_RETRY_COUNT = 5;// 10次

    @Autowired
    private ShardedRedisService shardedRedisService;

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        // 登录账号
        String username = (String)token.getPrincipal();
        // 缓存 key
        String passwordRetryCache = CacheConstants.SHIRO_PASSWORD_RETRY + username;
        // 超过次数则拒绝访问
        if (shardedRedisService.exists(passwordRetryCache)) {
            // 超过次数则拒绝访问
            if (shardedRedisService.incr(passwordRetryCache) > MAX_RETRY_COUNT) {
                throw new ExcessiveAttemptsException();
            }
        } else {
            shardedRedisService.set(passwordRetryCache, "1", MAX_RETRY_SECOND);
        }
        // 校验凭证
        boolean matches = super.doCredentialsMatch(token, info);
        // 成功则重置次数
        if(matches) {
            shardedRedisService.set(passwordRetryCache, "1", MAX_RETRY_SECOND);
        }
        return matches;
    }

}
